home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / tnos / tnos100s / ttydriv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-27  |  11.2 KB  |  564 lines

  1. /* TTY input line editing
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  * split screen by G. J. van der Grinten, PA0GRI
  4.  * fixed split screen ^B and ^W functions - KO4KS
  5.  */
  6. #include <stdio.h>
  7. #ifdef __TURBOC__
  8. #include <conio.h>
  9. #endif
  10. #include <ctype.h>
  11. #include "global.h"
  12. #include "config.h"
  13. #include "mbuf.h"
  14. #include "session.h"
  15. #include "tty.h"
  16. #include "socket.h"
  17.  
  18. extern FILE *Rawterm;
  19. extern unsigned char SCREENwidth, SCREENlength;
  20. #ifdef TNOS_68K
  21. extern short UseCurses;
  22. #endif
  23.  
  24. #define    OFF    0
  25. #define    ON    1
  26.  
  27. #define    LINESIZE    256
  28.  
  29. #ifndef CTLR
  30. #define CTLR    18      /* reprint current line */
  31. #define CTLU    21      /* delete current line in total */
  32. #define    CTLW    23        /* erase last word including preceding space */
  33. #define    CTLZ    26        /* EOF char in dos */
  34. #define    CTLB    02        /* use as F3 in dos but no editing */
  35. #endif
  36. #define DEL    0x7f
  37.  
  38. #ifdef ALLSERV
  39.  
  40. static int  Lastsize = 1;
  41. static char Lastline[LINESIZE+1] = "\n";
  42.  
  43. static void
  44. backspace ()
  45. {
  46. int x;
  47.     x = wherex();
  48. #ifdef TNOS_68K
  49.     if (!x && UseCurses)
  50. #else
  51.     if (x == 1)
  52. #endif
  53.         gotoxy(80, wherey() - 1);
  54.     else    {
  55. #ifdef TNOS_68K
  56.         if (UseCurses)
  57.             gotoxy(x - 1, wherey());
  58.         else
  59. #endif
  60.             cputs ("\b");
  61.     }
  62. }
  63.  
  64.  
  65. static void
  66. space()
  67. {
  68.     cputs(" ");
  69. }
  70.  
  71.  
  72. static void
  73. switchattr ()
  74. {
  75. #ifndef TNOS_68K
  76. struct text_info tr;
  77. unsigned char attr;
  78.  
  79.     gettextinfo(&tr);
  80.     attr = ((tr.attribute & 0x0f) << 4) + ((tr.attribute & 0x70) >> 4);
  81.     textattr (attr);
  82. #endif
  83. }
  84.  
  85.  
  86. static void
  87. tochatline(sp, gothere)
  88. struct session *sp;
  89. int gothere;
  90. {
  91. #ifndef TNOS_68K
  92.     sp->tsavex = wherex();
  93.     sp->tsavey = wherey();
  94.     window(1,SCREENlength - 1,SCREENwidth,SCREENlength);
  95.     switchattr ();
  96.     if (gothere)
  97.         gotoxy(sp->bsavex,sp->bsavey);
  98. #else
  99.     if (UseCurses)
  100.         sp->screen->win = sp->screen->splitwin;
  101. #endif
  102. }
  103.  
  104.  
  105. static void
  106. fromchatline(sp)
  107. struct session *sp;
  108. {
  109. #ifdef TNOS_68K
  110.     if (UseCurses)    {
  111. #endif
  112.         cputs("_");
  113.         backspace ();
  114. #ifdef TNOS_68K
  115.         sp->screen->win = sp->screen->textwin;
  116.     }
  117. #else
  118.     sp->bsavex = wherex();
  119.     sp->bsavey = wherey();
  120.     window(1,1 + sp->screen->statline,SCREENwidth,SCREENlength - 2);
  121.     switchattr ();
  122.     gotoxy(sp->tsavex,sp->tsavey);
  123. #endif
  124. }
  125.  
  126.  
  127. void
  128. clrchatline (sp)
  129. struct session *sp;
  130. {
  131.     tochatline (sp, 0);
  132. #ifdef TNOS_68K
  133.     if (UseCurses)    {
  134.         werase (sp->screen->win);
  135.         gotoxy (0, 0);
  136.     }
  137. #else
  138.     clrscr();
  139. #endif
  140.     fromchatline (sp);
  141. }
  142.  
  143.  
  144. /* Accept characters from the incoming tty buffer and process them
  145.  * (if in cooked mode) or just pass them directly (if in raw mode).
  146.  *
  147.  * Echoing (if enabled) is direct to the raw terminal. This requires
  148.  * recording (if enabled) of locally typed info to be done by the session
  149.  * itself so that edited output instead of raw input is recorded.
  150.  * Control-W added by g1emm again.... for word delete.
  151.  * Control-B/Function key 3 added by g1emm for line repeat.
  152.  */
  153.  
  154. struct mbuf *
  155. ttydriv(sp,c)
  156. struct session *sp;
  157. int c;
  158. {
  159.     struct mbuf *bp;
  160.     char *cp,*rp;
  161.     int cnt;
  162.  
  163.     switch(sp->ttystate.edit){
  164.     case OFF:
  165.         bp = ambufw(1);
  166.         *bp->data = c;
  167.         bp->cnt = 1;
  168.         if(sp->ttystate.echo){
  169.             if(sp->split){
  170.                 tochatline (sp, 1);
  171.                 putch(c);
  172.                 fromchatline (sp);
  173.             } else {
  174. #ifdef TNOS_68K
  175.                 putch(c);
  176. #else
  177.                 putc(c,Rawterm);
  178. #endif
  179.             }
  180.         }
  181. #ifdef TNOS_68K
  182.         rflush ();
  183. #endif
  184.         return bp;
  185.     case ON:
  186.         if(sp->ttystate.line == NULLBUF)
  187.             sp->ttystate.line = ambufw(LINESIZE);
  188.  
  189.         bp = sp->ttystate.line;
  190.         cp = bp->data + bp->cnt;
  191.         /* Perform cooked-mode line editing */
  192. #ifdef notdef
  193.         switch(c & 0x7f){
  194. #endif
  195.         /* Allow for international character sets - WG7J */
  196.         switch(c){
  197.         case '\r':  /* CR and LF both terminate the line */
  198. #ifdef TNOS_68K
  199.         case '\l':  /* CR and LF both terminate the line */
  200. #else
  201.         case '\n':
  202. #endif
  203.             if(sp->ttystate.crnl)
  204.                 *cp = '\n';
  205.             else
  206.                 *cp = c;
  207.             if(sp->ttystate.echo){
  208.                 if(sp->split){
  209. #ifdef TNOS_68K
  210.                     if (UseCurses)    {
  211. #endif
  212.                         highvideo();
  213.                         rp = bp->data;
  214.                         while(rp < cp)
  215.                             putch(*rp++);
  216.                         lowvideo();
  217.                         clreol();
  218. #ifdef TNOS_68K
  219.                     }
  220. #endif
  221.                     cputs(Eol);
  222.                     clreol();
  223.                     clrchatline(sp);
  224.                 } else {
  225. #ifdef TNOS_68K
  226.                     cputs(Eol);
  227. #else
  228.                     fputs(Eol,Rawterm);
  229. #endif
  230.                 }
  231.             }
  232.             bp->cnt += 1;
  233.             sp->ttystate.line = NULLBUF;
  234.             Lastsize = bp->cnt;
  235.             memcpy(Lastline, bp->data, Lastsize);            
  236.             return bp;
  237.         case DEL:
  238.         case '\b':    /* Character delete */
  239.             if(bp->cnt != 0){
  240.                 bp->cnt--;
  241.                 if(sp->ttystate.echo){
  242.                     if(sp->split){
  243.                         tochatline (sp, 1);
  244.                         space ();
  245.                         backspace ();
  246.                         backspace ();
  247.                         fromchatline (sp);
  248.                     } else {
  249.                         backspace();
  250.                         space ();
  251.                         backspace ();
  252.                     }
  253.                 }
  254.             }
  255.             break;
  256.         case CTLR:    /* print line buffer */
  257.             if(sp->ttystate.echo){
  258.                 if(sp->split) {
  259.                     tochatline (sp, 1);
  260. #ifdef TNOS_68K
  261.                     if (UseCurses)
  262.                         werase (sp->screen->win);
  263. #else
  264.                     clrscr();
  265. #endif
  266.                     rp = bp->data;
  267.                     while (rp < cp)
  268.                         putch(*rp++) ;
  269.                     fromchatline (sp);
  270.                 } else {
  271. #ifdef TNOS_68K
  272.                 cnt = bp->cnt;
  273.                 while(cnt != 0){
  274.                     cnt--;
  275.                     if(sp->ttystate.echo)    {
  276.                         backspace ();
  277.                         space ();
  278.                         backspace ();
  279.                     }
  280.                 }
  281. #else
  282.                     fprintf(Rawterm,"^R%s",Eol) ;
  283. #endif
  284.                     rp = bp->data;
  285.                     while (rp < cp)
  286. #ifdef TNOS_68K
  287.                         putch(*rp++) ;
  288. #else
  289.                         putc(*rp++,Rawterm) ;
  290. #endif
  291.                 }
  292.             }
  293.             break ;
  294.         case CTLU:    /* Line kill */
  295.             if(sp->split) {
  296.                 clrchatline (sp);
  297.                 bp->cnt = 0;
  298.             } else {
  299.                 while(bp->cnt != 0){
  300.                     bp->cnt--;
  301.                     if(sp->ttystate.echo)    {
  302.                         backspace ();
  303.                         space ();
  304.                         backspace ();
  305.                     }
  306.                 }
  307.             }
  308.             break;
  309.         case CTLB:    /* Use last line to finish current */
  310.             if(!sp->split)    {
  311.                 cnt = bp->cnt;        /* save count so far */
  312.  
  313.                 while(bp->cnt != 0){
  314.                     bp->cnt--;
  315.                     if(sp->ttystate.echo)    {
  316.                         backspace ();
  317.                         space ();
  318.                         backspace ();
  319.                     }
  320.                 }
  321.                 bp->cnt = cnt;
  322.             }
  323.  
  324.                         if(bp->cnt < (Lastsize-1)){
  325.                                 memcpy(bp->data+bp->cnt, &Lastline[bp->cnt], (Lastsize-1) - bp->cnt);
  326.                                 bp->cnt = Lastsize-1;
  327.             }
  328.  
  329.             *(bp->data + bp->cnt) = '\0';    /* make it a string */
  330.             if(sp->ttystate.echo)
  331.                 if(sp->split) {
  332.                     tochatline (sp, 1);    /* was 0    */
  333. #ifdef TNOS_68K
  334.                     if (UseCurses)
  335.                         werase (sp->screen->win);
  336. #else
  337.                     clrscr();
  338. #endif
  339.                     cputs (bp->data);
  340.                     fromchatline (sp);
  341.                 } else 
  342. #ifdef TNOS_68K
  343.                     cputs (bp->data);
  344. #else
  345.                     fputs(bp->data, Rawterm);    /* repaint line */
  346. #endif
  347.             break ;
  348.         case CTLW:    /* erase word */
  349.             if(sp->split)
  350.                 if (sp->ttystate.echo)    {
  351.                     tochatline (sp, 1);
  352.                     space ();
  353.                     backspace ();
  354.                 }
  355.             cnt = 0 ;    /* we haven't seen a printable char yet */
  356.             while(bp->cnt != 0){
  357.                 *(bp->data + bp->cnt--) = '\n';
  358.                 if(sp->ttystate.echo)
  359.                     if (sp->split)    {
  360.                         backspace ();
  361.                         space ();
  362.                         backspace ();
  363.                     }
  364.                     else    {
  365.                         backspace ();
  366.                         space ();
  367.                         backspace ();
  368.                     }
  369.                 if (isspace((int)*(bp->data + bp->cnt))) {
  370.                     if (cnt)
  371.                         break ;
  372.                 } else {
  373.                     cnt = 1 ;
  374.                 }
  375.             }
  376.             if(sp->split && sp->ttystate.echo)
  377.                 fromchatline (sp);
  378.             break ;
  379.         case UPARROW:  /* Recall previous command - WG7J */
  380.         case DNARROW:  /* Recall next command - WG7J */
  381.             if(Histry) {
  382.                 /* Blank out what's already there */
  383.                 while(bp->cnt != 0 && sp->ttystate.echo){
  384.                     bp->cnt--;
  385.                     cputs("\b \b");
  386.                 }
  387.                 if (c == DNARROW)
  388.                     /* Adjust history */
  389.                     Histry = Histry->next;
  390.                 /* Recall last command */
  391.                 strcpy(bp->data,Histry->cmd);
  392.                 bp->cnt = strlen(Histry->cmd);
  393.                 if (c == UPARROW)
  394.                     /* Adjust history */
  395.                     Histry = Histry->prev;
  396.                 /* repaint line */
  397.                 if(sp->ttystate.echo)
  398.                     cputs(bp->data);
  399.             }
  400.             break ;
  401.         default:    /* Ordinary character */
  402.             *cp = c;
  403.             bp->cnt++;
  404.  
  405.             /* ^Z apparently hangs the terminal emulators under
  406.              * DoubleDos and Desqview. I REALLY HATE having to patch
  407.              * around other people's bugs like this!!!
  408.              */
  409.             if(sp->ttystate.echo &&
  410. #ifndef    AMIGA
  411.              c != CTLZ &&
  412. #endif
  413.              bp->cnt < LINESIZE-1){
  414.                 if(sp->split) {
  415.                     tochatline (sp, 1);
  416.                     putch(c);
  417.                     fromchatline (sp);
  418.                 } else {
  419. #ifdef TNOS_68K
  420.                     putch(c);
  421. #else
  422.                     putc(c,Rawterm);
  423. #endif
  424.                 }
  425.  
  426.             } else if(bp->cnt >= LINESIZE-1){
  427. #ifdef TNOS_68K
  428.                 putch('\007');    /* Beep */
  429. #else
  430.                 putc('\007',Rawterm);    /* Beep */
  431. #endif
  432.                 bp->cnt--;
  433.             }
  434.             break;
  435.         }
  436.         break;
  437.     }
  438. #ifdef TNOS_68K
  439.     rflush ();
  440. #endif
  441.     return NULLBUF;
  442. }
  443.  
  444. #else
  445.  
  446.  
  447. /* Accept characters from the incoming tty buffer and process them
  448.  * (if in cooked mode) or just pass them directly (if in raw mode).
  449.  *
  450.  * Echoing (if enabled) is direct to the raw terminal. This requires
  451.  * recording (if enabled) of locally typed info to be done by the session
  452.  * itself so that edited output instead of raw input is recorded.
  453.  */
  454. struct mbuf *
  455. ttydriv(sp,c)
  456. struct session *sp;
  457. int c;
  458. {
  459.     struct mbuf *bp;
  460.     char *cp,*rp;
  461.  
  462.     switch(sp->ttystate.edit){
  463.     case OFF:
  464.         bp = ambufw(1);
  465.         *bp->data = c;
  466.         bp->cnt = 1;
  467.         if(sp->ttystate.echo)
  468.             putc(c,Rawterm);
  469.  
  470.         return bp;
  471.     case ON:
  472.         if(sp->ttystate.line == NULLBUF)
  473.             sp->ttystate.line = ambufw(LINESIZE);
  474.  
  475.         bp = sp->ttystate.line;
  476.         cp = bp->data + bp->cnt;
  477.         /* Perform cooked-mode line editing */
  478.         switch(c & 0x7f){
  479.         case '\r':    /* CR and LF both terminate the line */
  480.         case '\n':
  481.             if(sp->ttystate.crnl)
  482.                 *cp = '\n';
  483.             else
  484.                 *cp = c;
  485.             if(sp->ttystate.echo)
  486.                 fputs(Eol,Rawterm);
  487.  
  488.             bp->cnt += 1;
  489.             sp->ttystate.line = NULLBUF;
  490.             return bp;
  491.         case DEL:
  492.         case '\b':    /* Character delete */
  493.             if(bp->cnt != 0){
  494.                 bp->cnt--;
  495.                 if(sp->ttystate.echo)
  496.                     fputs("\b \b",Rawterm);
  497.             }
  498.             break;
  499.         case CTLR:    /* print line buffer */
  500.             if(sp->ttystate.echo){
  501.                 fprintf(Rawterm,"^R%s",Eol) ;
  502.                 rp = bp->data;
  503.                 while (rp < cp)
  504.                     putc(*rp++,Rawterm) ;
  505.             }
  506.             break ;
  507.         case CTLU:    /* Line kill */
  508.             while(bp->cnt != 0){
  509.                 bp->cnt--;
  510.                 if(sp->ttystate.echo){
  511.                     fputs("\b \b",Rawterm);
  512.                 }
  513.             }
  514.             break;
  515.         case UPARROW:  /* Recall previous command - WG7J */
  516.         case DNARROW:  /* Recall next command - WG7J */
  517.             if(Histry) {
  518.                 /* Blank out what's already there */
  519.                 while(bp->cnt != 0 && sp->ttystate.echo){
  520.                     bp->cnt--;
  521.                     cputs("\b \b");
  522.                 }
  523.                 if (c == DNARROW)
  524.                     /* Adjust history */
  525.                     Histry = Histry->next;
  526.                 /* Recall last command */
  527.                 strcpy(bp->data,Histry->cmd);
  528.                 bp->cnt = strlen(Histry->cmd);
  529.                 if (c == UPARROW)
  530.                     /* Adjust history */
  531.                     Histry = Histry->prev;
  532.                 /* repaint line */
  533.                 if(sp->ttystate.echo)
  534.                     cputs(bp->data);
  535.             }
  536.             break ;
  537.         default:    /* Ordinary character */
  538.             *cp = c;
  539.             bp->cnt++;
  540.  
  541.             /* ^Z apparently hangs the terminal emulators under
  542.              * DoubleDos and Desqview. I REALLY HATE having to patch
  543.              * around other people's bugs like this!!!
  544.              */
  545.             if(sp->ttystate.echo &&
  546. #ifndef    AMIGA
  547.              c != CTLZ &&
  548. #endif
  549.              bp->cnt < LINESIZE-1){
  550.                 putc(c,Rawterm);
  551.  
  552.             } else if(bp->cnt >= LINESIZE-1){
  553.                 putc('\007',Rawterm);    /* Beep */
  554.                 bp->cnt--;
  555.             }
  556.             break;
  557.         }
  558.         break;
  559.     }
  560.     return NULLBUF;
  561. }
  562.  
  563. #endif /*ALLSERV*/
  564.